#pragma once
#include <stack>
#define MEM_ALIGN 4

//author: Gordon Koefner
//Memory stack with alignment, pointers aligned to MEM_ALIGN with adjustable alignment
class MemoryStack
{
public:
	MemoryStack(size_t size, size_t alignment);
	~MemoryStack(void);

	//push an element with the given size onto the stack
	void* push(size_t size);

	//remove the top element from the stack
	void pop();

	//get pointer to the top element on the stack
	void* top();

protected:
	//makes first parameter divisible by the second parameter by enlarging it.
	size_t getAlignedSize(size_t origSize, size_t align);

	//prints an error on stderr and exits application
	void error(char* err, int exitCode);

	std::stack<size_t> elementSizes; //stores the sizes of the elements in the stack, needed for pop

	void* topPtr; //pointer to the top of the stack (next pushed element will have this address)
	void* origin; //pointer to the beginning of the stack
	size_t stackSize; //used for stack overflow check
	size_t alignment; //alignment of elements in the stack (size of block needs to be divisible by this)
};

